#ifndef MS5611_DRIVER_H
#define MS5611_DRIVER_H

#include "stm32f4xx_hal.h"
#include <stdint.h>
#include <math.h>

// MS5611 地址和命令
#define MS5611_OK 0x01
#define MS5611_ERROR 0x00
//MS5611 ADDR CSB
#define MS5611_SLAVE_ADDR 0XEE

//COMMAND
#define MS5611_CMD_REST 0X1E
#define MS5611_CMD_CONVERT_D1_256 0X40
#define MS5611_CMD_CONVERT_D1_512 0X42
#define MS5611_CMD_CONVERT_D1_1024 0X44
#define MS5611_CMD_CONVERT_D1_2048 0X46
#define MS5611_CMD_CONVERT_D1_4096 0X48
#define MS5611_CMD_CONVERT_D2_256 0X50
#define MS5611_CMD_CONVERT_D2_512 0X52
#define MS5611_CMD_CONVERT_D2_1024 0X54
#define MS5611_CMD_CONVERT_D2_2048 0X56
#define MS5611_CMD_CONVERT_D2_4096 0X58

#define MS6511_ADC_READ 0X00

#define MS5611_PROM_READ_0 0XA0
#define MS5611_PROM_READ_1 0XA2
#define MS5611_PROM_READ_2 0XA4
#define MS5611_PROM_READ_3 0XA6
#define MS5611_PROM_READ_4 0XA8
#define MS5611_PROM_READ_5 0XAA
#define MS5611_PROM_READ_6 0XAC
#define MS5611_PROM_READ_7 0XAE

typedef struct
{
    uint8_t adress;
    uint16_t C[6];    //PROM
    uint16_t reserve;
    uint16_t crc;
    uint32_t D[2];    //D1 temperature data & D2 pressure data
    int32_t dT;    //Difference between actual and reference temperature
    int64_t OFF;    //Offset at actual temperature
    int64_t SENS;    //Sensitivity at actual temperature
    int32_t TEMP;    //Actual temperature
    int32_t P;    //Actual pressure
}MS5611_t;

typedef struct {
    float x;  // ???
    float P;  // ?????
    float Q;  // ???????
    float R;  // ???????
} KalmanFilter;

// 函数声明
void MS5611_Rest(I2C_HandleTypeDef* I2Cx);
uint8_t MS5611_init(I2C_HandleTypeDef* I2Cx, MS5611_t* datastruct);
uint8_t MS5611_PROM_read(I2C_HandleTypeDef* I2Cx, MS5611_t* datastruct);
uint8_t MS5611_read_temp(I2C_HandleTypeDef* I2Cx, MS5611_t* datastruct, uint8_t resolution);
uint8_t NB_MS5611_request_temp(I2C_HandleTypeDef* I2Cx, MS5611_t* datastruct, uint8_t resolution);
uint8_t NB_MS5611_pull_temp(I2C_HandleTypeDef* I2Cx, MS5611_t* datastruct);
uint8_t MS5611_read_press (I2C_HandleTypeDef* I2Cx, MS5611_t* datastruct, uint8_t resolution);
uint8_t NB_MS5611_request_press (I2C_HandleTypeDef* I2Cx, MS5611_t* datastruct, uint8_t resolution);
uint8_t NB_MS5611_pull_press (I2C_HandleTypeDef* I2Cx, MS5611_t* datastruct);
uint8_t MS5611_calculate(MS5611_t* datastruct);
double mbar_to_height(double pressure_mbar) ;

void kalman_init(KalmanFilter *kf, float initial_x, float initial_P, float process_noise, float measurement_noise);
void kalman_predict(KalmanFilter *kf, float control_input);
void kalman_update(KalmanFilter *kf, float measurement);

#define MAXLENGTH 28000

float get_height(int index);


#endif // MS5611_DRIVER_H


//KalmanFilter kf;


//MS5611_init(&hi2c1,&ms5611_t);
//MS5611_PROM_read(&hi2c1,&ms5611_t);
//// 初始化卡尔曼滤波�??
//kalman_init(&kf, 1012.0, 1.0, 0.005, 0.1);


//kalman_predict(&kf, 0.0);
//MS5611_read_press(&hi2c1,&ms5611_t,MS5611_CMD_CONVERT_D2_4096);
//MS5611_read_temp(&hi2c1,&ms5611_t,MS5611_CMD_CONVERT_D2_4096);
//MS5611_calculate(&ms5611_t);
//
//char press[20];
//sprintf(press,"%f",((double)ms5611_t.P/100));
//
//OLED_ShowString(1, 1,press );
//
//char press_km[20];
//kalman_update(&kf, ((double)ms5611_t.P/100));
//sprintf(press_km,"%.3f",kf.x);
//OLED_ShowString(2, 1, press_km);
//
//int kx=kf.x*1000;
//char press_trans[20];
//	  sprintf(press_trans,"%.2f",get_height(1013560 - kx));
//OLED_ShowString(3, 1, press_trans);
